package com.tenebrous.jestic.service.framwork.meber.author;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tenebrous.jestic.entity.TreeSerializable;
import com.tenebrous.jestic.entity.framwork.meber.author.*;
import com.tenebrous.jestic.entity.framwork.meber.author.*;
import com.tenebrous.jestic.entity.framwork.meber.organ.OrgUser;
import com.tenebrous.jestic.mapper.idao.framwork.meber.author.*;
import com.tenebrous.jestic.mapper.idao.framwork.meber.author.*;
import com.tenebrous.jestic.service.SuperService;
import com.rain.ops.sdk.utils.UUIDUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class AuthRoleService extends SuperService<AuthRole> {

    @Autowired
    private AuthRoleMapper mapper;

    @Autowired
    private AuthMenuMapper menuMapper;

    @Autowired
    private AuthRoleMenuMapper rolemenuMapper;

    @Autowired
    private AuthRoleUserMapper roleuserMapper;

    @Autowired
    private AuthRoleRouterMapper roleRouterMapper;

    @Autowired
    private AuthRoleProcessMapper roleProcessMapper;

    @Override
    @Autowired
    protected void setSuperMapper() {

        super.setSuperMapper(this.mapper);
    }

    public AuthRoleRouter getRoleRouter(String id) {
        return this.roleRouterMapper.selectByPrimaryKey(id);
    }

    public List<TreeSerializable> queryRoleMenuList(String rid) {

        List<String> mids = this.mapper.selectMenuIdsByRoleid(rid);

        List<AuthMenu> mlist = this.menuMapper.selectByCondition();
        for (AuthMenu mitem : mlist) {
            if (mids.contains(mitem.getId())) {
                mitem.setSelected(true);
            }
        }
        List<TreeSerializable> tlist = new ArrayList<>();
        tlist.addAll(mlist);

        return this.buildTree(tlist, "0");
    }

    public List<OrgUser> queryRoleUserList(String roleid) {
        return this.queryRoleUserList(roleid, null);
    }

    public List<OrgUser> queryRoleUserList(String roleid, String realname) {
        return this.mapper.selectUserListByRoleid(roleid, realname);
    }

    public List<AuthRole> queryUserRoleList(String userid) {
        return this.queryUserRoleList(userid, null);
    }

    public List<AuthRole> queryUserRoleList(String userid, String rolename) {
        return this.mapper.selectRoleListByUserid(userid, rolename);
    }

    public PageInfo<OrgUser> queryPagingRoleUserList(Integer pageIndex, Integer pageSize, String rid, String realname) {
        return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> this.queryRoleUserList(rid, realname));
    }

    public PageInfo<AuthRole> queryPagingUserRoleList(Integer pageIndex, Integer pageSize, String userid, String rolename) {
        return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> this.queryUserRoleList(userid, rolename));
    }

    public PageInfo<AuthRole> queryPagingList(Integer pageIndex, Integer pageSize, String name) {
        return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> this.mapper.selectByCondition(name));
    }

    @Transactional
    public int updateRoleMenus(String roleid, String[] menuids) {
        int i = 0;
        Date dt = new Date();
        this.mapper.deleteRoleMenuByCondition(roleid);
        for (String menuid : menuids) {
            AuthRoleMenu item = new AuthRoleMenu();
            item.setId(UUIDUtils.randomUUID());
            item.setRoleid(roleid);
            item.setMenuid(menuid);
            item.setCreateDate(dt);

            this.rolemenuMapper.insertSelective(item);
            i++;
        }
        return i;
    }

    @Transactional
    public int updateRoleProcess(String roleid, String[] pids) {
        int i = 0;
        this.mapper.deleteRoleProcessByCondition(roleid, null);
        for (String procdefid : pids) {
            AuthRoleProcess item = new AuthRoleProcess();
            item.setRoleid(roleid);
            item.setProcdefid(procdefid);
            item.setCreateDate( new Date());
            item.setId(UUIDUtils.randomUUID());
            i += this.roleProcessMapper.insertSelective(item);
        }
        return i;
    }

    @Transactional
    public int updateUserRoles(String uid, String[] rids) {
        int i = 0;
        Date dt = new Date();
        this.mapper.deleteRoleUserByCondition(null, uid);
        for (String roleid : rids) {
            AuthRoleUser item = new AuthRoleUser();
            item.setId(UUIDUtils.randomUUID());
            item.setRoleid(roleid);
            item.setUserid(uid);
            item.setCreateDate(dt);

            this.roleuserMapper.insertSelective(item);
            i++;
        }
        return i;
    }

    @Transactional
    public int insertUserRoles(String uid, String[] rids) {
        int i = 0;
        Date dt = new Date();
        for (String roleid : rids) {
            AuthRoleUser ru = new AuthRoleUser();
            ru.setUserid(uid);
            ru.setRoleid(roleid);
            if(this.roleuserMapper.selectCount(ru) == 0) {
                AuthRoleUser item = new AuthRoleUser();
                item.setId(UUIDUtils.randomUUID());
                item.setRoleid(roleid);
                item.setUserid(uid);
                item.setCreateDate(dt);

                this.roleuserMapper.insertSelective(item);
                i++;
            }
        }
        return i;
    }

    @Transactional
    public int insertRoleUsers(String roleid, String[] userids) {
        int i = 0;
        Date dt = new Date();
        for (String userid : userids) {
            AuthRoleUser item = this.roleuserMapper.selectByRoleidAndUserid(roleid, userid);
            if(item == null) {
                item = new AuthRoleUser();
                item.setId(UUIDUtils.randomUUID());
                item.setRoleid(roleid);
                item.setUserid(userid);
                item.setCreateDate(dt);
                this.roleuserMapper.insertSelective(item);
                i++;
            }
        }
        return i;
    }

    @Transactional
    public int insertRoleProcess(String roleid, String[] pids) {
        int i = 0;
        Date dt = new Date();
        for (String procdefid : pids) {
            AuthRoleProcess rp = new AuthRoleProcess();
            rp.setRoleid(roleid);
            rp.setProcdefid(procdefid);
            if(this.roleProcessMapper.selectCount(rp) == 0) {
                AuthRoleProcess item = new AuthRoleProcess();
                item.setId(UUIDUtils.randomUUID());
                item.setProcdefid(procdefid);
                item.setRoleid(roleid);
                item.setCreateDate(dt);
                i += this.roleProcessMapper.insertSelective(item);
            }
        }
        return i;
    }

    public int updateRoleRouter(AuthRoleRouter item) {
        if (StringUtils.isNotBlank(item.getId())) {
            AuthRoleRouter router = this.roleRouterMapper.selectByPrimaryKey(item.getId());
            if (router != null) {
                item.setUpdateDate(new Date());
                return this.roleRouterMapper.updateByPrimaryKeySelective(item);
            } else {
                item.setCreateDate(new Date());
                return this.roleRouterMapper.insertSelective(item);
            }
        }
        return 0;
    }

    @Transactional
    public int deleteById(String roleid) {
        this.mapper.deleteById(roleid);
        return 1;
    }

    @Transactional
    public int deleteByIds(String[] roleids) {
        int i = 0;
        for (String id : roleids) {
            if (StringUtils.isNotBlank(id)) {
                this.mapper.deleteById(id);
                i++;
            }
        }
        return i;
    }

    @Transactional
    public int deleteRoleUsers(String roleid, String[] userids) {
        int i = 0;
        for (String userid : userids) {
            this.mapper.deleteRoleUserByCondition(roleid, userid);
            i++;
        }
        return i;
    }

    @Transactional
    public int deleteRoleProcess(String roleid, String[] procdefids) {
        int i = 0;
        for (String procdefid : procdefids) {
            this.mapper.deleteRoleProcessByCondition(roleid, procdefid);
            i ++;
        }
        return i;
    }

    @Transactional
    public int deleteUserRoles(String userid, String[] roleids) {
        int i = 0;
        for (String roleid : roleids) {
            this.mapper.deleteRoleUserByCondition(roleid, userid);
            i++;
        }
        return i;
    }
}
